<template>
  <div>
    <el-select
      v-if="itemType === 'select'"
      v-bind="$attrs"
      v-model="data"
      filterable
      :clearable="!noClear"
      style="width: 100%"
      @change="onChange"
    >
      <el-option
        v-for="(item, index) in selections"
        :key="index"
        :label="getObjectFromKey(item, valProp?.key ?? 'label')"
        :value="getObjectFromKey(item, valProp?.value ?? 'value')"
      />
      <template v-for="slot in Object.keys($slots)" #[slot] />
    </el-select>

    <el-select
      v-else-if="itemType === 'flatSelect'"
      v-model="data"
      filterable
      :clearable="!noClear"
      style="width: 100%"
      v-bind="$attrs"
      @change="onChange"
    >
      <el-option
        v-for="(item, index) in selections"
        :key="index"
        :label="item"
        :value="item"
      />
      <template v-for="slot in Object.keys($slots)" #[slot] />
    </el-select>

    <el-input
      v-else-if="itemType === 'input'"
      v-bind="$attrs"
      v-model="data"
      clearable
      @change="onChange"
    >
      <template v-if="dividerName" #append>{{ dividerName }}</template>
      <template v-for="slot in Object.keys($slots)" #[slot] />
    </el-input>

    <el-input
      v-else-if="itemType === 'password'"
      v-model="data"
      type="password"
      clearable
      v-bind="$attrs"
      @change="onChange"
    >
      <template v-if="dividerName" #append>{{ dividerName }}</template>
      <template v-for="slot in Object.keys($slots)" #[slot] />
    </el-input>

    <el-input-number
      v-else-if="itemType === 'number'"
      v-model="data"
      onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))"
      v-bind="$attrs"
      @change="onChange"
    >
      <template v-if="dividerName" #append>{{ dividerName }}</template>
      <template v-for="slot in Object.keys($slots)" #[slot] />
    </el-input-number>

    <el-input-number
      v-else-if="itemType === 'clearNumber'"
      v-model="data"
      class="custom-clear-number"
      controls-position="right"
      onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))"
      v-bind="$attrs"
      @change="onChange"
    >
      <template v-if="dividerName" #append>{{ dividerName }}</template>
      <template v-for="slot in Object.keys($slots)" #[slot] />
    </el-input-number>

    <div v-else-if="itemType === 'checkbox'">
      <el-checkbox-group v-bind="$attrs" v-model="data" @change="onChange">
        <el-checkbox
          v-for="(item, index) in checks"
          :key="index"
          :label="getObjectFromKey(item, valProp.value ?? 'value')"
        >
          {{ getObjectFromKey(item, valProp.label ?? "label") }}
        </el-checkbox>
      </el-checkbox-group>
    </div>

    <div
      v-else-if="itemType === 'radio' && radioLayout === 'vertical'"
      style="display: block"
    >
      <el-radio-group v-bind="$attrs" v-model="data" @change="onChange">
        <el-radio
          v-for="(item, index) in radios"
          :key="index"
          :disabled="item.disabledOption"
          :label="item.value"
          style="display: block; line-height: 25px"
        >
          {{ item.label }}
        </el-radio>
      </el-radio-group>
    </div>
    <div v-else-if="itemType === 'radio' && !radioLayout">
      <el-radio-group v-bind="$attrs" v-model="data">
        <el-radio
          v-for="(item, index) in radios"
          :key="index"
          :disabled="item.disabledOption"
          :label="item.value"
        >
          {{ item.label }}
        </el-radio>
      </el-radio-group>
    </div>
    <el-input
      v-else-if="itemType === 'textarea'"
      v-model="data"
      v-bind="$attrs"
      style="width: 100%"
      type="textarea"
      :rows="rows"
      :autosize="{ maxRows: 10 }"
      @change="onChange"
    >
      <template v-if="dividerName" #append>{{ dividerName }}</template>
    </el-input>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted } from "vue";
import { getObjectFromKey } from "../../../utils";

export type ComponentType =
  | "select"
  | "input"
  | "password"
  | "number"
  | "clearNumber"
  | "checkbox"
  | "radio"
  | "flatSelect"
  | "textarea";

type Prop = {
  itemType?: ComponentType;
  selections?: any[];
  noClear?: boolean;
  dividerName?: string;
  radios?: any[];
  radioLayout?: string;
  checks?: any[];
  valProp?: { key: string; value: string; label: string };
  default?: any;
  rows?: number;
  getter?: () => any;
  setter?: (val: any) => void;
};
const props = defineProps<Prop>();
const emit = defineEmits(["onChange"]);

const onChange = (val: any) => {
  emit("onChange", val);
};

const _data = defineModel();
const data = computed({
  get: () => {
    if (props.getter) {
      return props.getter();
    } else if (_data.value) {
      return _data.value;
    } else if (props.default) {
      return props.default;
    }
    return null;
  },
  set: val => {
    if (props.setter) {
      props.setter(val);
    } else {
      _data.value = val;
    }
  }
});

onMounted(() => {
  if (props.default && !_data.value) {
    _data.value = props.default;
  }
});
</script>

<style lang="scss">
.custom-clear-number {
  width: 100%;

  > .el-input-number__decrease {
    display: none;
  }

  > .el-input-number__increase {
    display: none;
  }

  > .el-input .el-input__wrapper {
    padding-right: 15px;

    .el-input__inner {
      text-align: start;
    }
  }
}
</style>
